/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ArkMethod, ClassSignature, MethodSignature, Stmt, ArkAssignStmt, Local, ArkInvokeStmt,
        ts, AstTreeUtils, ArkFile, ArkNamespace, Value, FieldSignature, AbstractBinopExpr,
        NamespaceSignature, ArkReturnStmt, AbstractInvokeExpr, ArkIfStmt, FunctionType, ImportInfo
      } from 'arkanalyzer/lib';
import { ArkClass } from 'arkanalyzer/lib/core/model/ArkClass';
import { BaseChecker, BaseMetaData } from '../BaseChecker';
import { RuleListUtil } from '../../utils/common/DefectsList';
import { FileMatcher, MatcherCallback, MatcherTypes } from '../../matcher/Matchers';
import { CheckerUtils } from '../../utils/checker/CheckerUtils';
import { Defects, IssueReport } from '../../model/Defects';
import { Rule } from '../../model/Rule';
type Var_base = { name?: string; type?: { name?: string }; usedStmts?: Stmt[]; declaringStmt?: Stmt; };
const leftNameReg = /\[|\]/g;
const objectArrayPatternsReg = /(\w+):\s*(\[[^\]]+\])/g;
const arrayElementsReg = /^\[|\]$/g;
const accuratePositionReg = /[.*+?^=!:${}()|\[\]\/\\]/g;
const textUsedReg = /[.*+?^${}()|[\]\\]/g;
type Method_Param = { arrayElements?: { name?: string }[]; name: string; objElements: []; };
type astType = { name: string; kind: string; line: number; character: number };
enum VarType { Var = 'var', Class = 'class', Import = 'import', Method = 'method', Type = 'type',
               Args = 'args', ArgsP = 'ArrayBindingPattern', Catch = 'catch', Static = 'static',
               UsedIgnorePattern = 'UsedIgnorePattern',
              }
type noUseVars = {
  varType: VarType; //方法名称
  stmt?: Stmt;
  arkClass?: ArkClass; //获取类信息
  arkNamespace?: ArkNamespace; //命名空间信息
  declareStmt?: Stmt; //有方法或者类不能固定
  name: string | string[]; //解构-特殊情况
  local?: 'local' | 'all'; //本地或者全局
  isMethodParam?: boolean; //是否是方法参数
  arkMethod?: ArkMethod; //方便获取方法的位置信息20250207
  isRestSiblings?: boolean; //是否与解构同级
  methodName?: string; //方法名称
  parammaxUsedIndex?: number; //被使用最大参数下标
  paramIndex?: number; //用于方法参数的判定
  static?: boolean; //是否是静态
  varInit?: boolean; //2025-02-07 优化方案
  ArrayBindingPattern?: boolean;
  argPosion?: [lineNo: number, strClo: number, endClo: number]; //记录缺失的位置信息
  filePath?: string; //参数stmt不包含
};
type Options = 'all' | 'local' | {
      args?: 'after-used' | 'all' | 'none';
      argsIgnorePattern?: string;
      caughtErrors?: 'all' | 'none';
      caughtErrorsIgnorePattern?: string;
      destructuredArrayIgnorePattern?: string;
      ignoreClassWithStaticInitBlock?: boolean;
      ignoreRestSiblings?: boolean;
      reportUsedIgnorePattern?: boolean;
      vars?: 'all' | 'local';
      varsIgnorePattern?: string;
    };
//对参数进行解释
interface TranslatedOptions {
  args: 'after-used' | 'all' | 'none'; //检查使用之后的----全部----不检查
  argsIgnorePattern?: RegExp; //忽略特定格式函数参数
  caughtErrors: 'all' | 'none'; //处理捕获的错误
  caughtErrorsIgnorePattern?: RegExp; //忽略特定
  destructuredArrayIgnorePattern?: RegExp; //忽略解构数组
  ignoreClassWithStaticInitBlock: boolean; //忽略静态代码块
  ignoreRestSiblings: boolean; //结构赋值中忽略兄弟元素->它控制在使用**对象解构赋值（destructuring）和剩余属性（rest property）**时，是否将剩余属性的同级属性视为未使用的变量。
  reportUsedIgnorePattern: boolean; //是否报告那些匹配忽略模式的变量
  vars: 'all' | 'local'; //处理变脸范围all全局 local允许全局
  varsIgnorePattern?: RegExp; //忽略指定匹配模式
}
const defaultOptions: TranslatedOptions = {
  args: 'all',
  caughtErrors: 'all',
  ignoreClassWithStaticInitBlock: false,
  ignoreRestSiblings: false,
  reportUsedIgnorePattern: false,
  vars: 'all',
};
const gMetaData: BaseMetaData = {
  severity: 1,
  ruleDocPath: 'docs/no-unused-vars-check.md',
  description: `Require 'compare' argument.`,
};
//编译过程中检测未使用的本地变量和参数
export class NoUnusedVarsCheck implements BaseChecker {
  readonly metaData: BaseMetaData = gMetaData;
  readonly SHORT_STR: string = 'sort';
  public rule: Rule;
  public defects: Defects[] = [];
  public issues: IssueReport[] = [];
  private clsMatcher: FileMatcher = {
    matcherType: MatcherTypes.FILE,
  };
  public registerMatchers(): MatcherCallback[] {
    const matchBuildCb: MatcherCallback = {
      matcher: this.clsMatcher,
      callback: this.check,
    };
    return [matchBuildCb];
  }
  public check = (targetFile: ArkFile) => {
    const exportInfos = targetFile.getExportInfos();
    const exportNames = exportInfos.map((info) => {
      // 如果 nameBeforeAs 存在且不为空，则使用它；否则使用 exportClauseName
      return info.getNameBeforeAs() || info.getOriginName();
    });
    const namespaces = this.getAllNamespaces(targetFile);
    let astRoot = AstTreeUtils.getASTNode(targetFile.getName(), targetFile.getCode());
    let nousedSet: noUseVars[] = [];
    let unuseds: noUseVars[] = [];
    const targetFilePath = targetFile.getFilePath();
    const options: Options = this.rule.option[0] as unknown as Options;
    const mergedOptions: TranslatedOptions = defaultOptions;
    this.mergedOptions(options, mergedOptions); //options参数赋值
    //未使用的方法集合
    const collectClass = this.collectUnusedClasses(targetFile, exportNames, mergedOptions);
    nousedSet = nousedSet.concat(collectClass);
    //处理命名空间
    const collectNameSpaces = this.collectUnusednameSpaces( namespaces, targetFile, exportNames, mergedOptions);
    nousedSet = nousedSet.concat(collectNameSpaces);
    //处理import + 处理type + 处理泛型
    const importInfos = targetFile.getImportInfos();
    const importNoused = this.noUsedImport(astRoot);
    const collectImports = this.collecUnusedImports(importInfos, targetFilePath, importNoused);
    nousedSet = nousedSet.concat(collectImports);
    const noUsedtype = this.noUsedType(astRoot); //包含interface便于处理
    const collectTypes = this.collecUnusedTypes(noUsedtype, targetFilePath);
    nousedSet = nousedSet.concat(collectTypes);
    const generics = this.getUnusedGenerics(astRoot);
    const noUsedGenerics = this.collecUnusedGenerics(generics, targetFilePath);
    nousedSet = nousedSet.concat(noUsedGenerics);
    unuseds = this.filterUnuseds(mergedOptions, nousedSet);
    for (const unused of unuseds) {
      this.addIssueReport(unused);
    }
  };
  private mergedOptions(
    options: Options,
    mergedOptions: TranslatedOptions
  ): void {
    if (typeof options === 'string') {
      mergedOptions.vars = options;
    } else {
      this.mergeArgs(options, mergedOptions);
      this.mergeCaughtErrors(options, mergedOptions);
      this.mergeDestructuredArray(options, mergedOptions);
      this.mergeBooleanFlags(options, mergedOptions);
      this.mergeVars(options, mergedOptions);
    }
  }
  private mergeArgs(options: Options, mergedOptions: TranslatedOptions): void {
    if (typeof options === 'object' && options?.args) {
      mergedOptions.args = options.args;
    }
    if (typeof options === 'object' && options?.argsIgnorePattern) {
      mergedOptions.argsIgnorePattern = new RegExp(options.argsIgnorePattern);
    }
  }
  private mergeCaughtErrors(options: Options, mergedOptions: TranslatedOptions): void {
    if (typeof options === 'object' && options?.caughtErrors) {
      mergedOptions.caughtErrors = options.caughtErrors;
    }
    if (typeof options === 'object' && options?.caughtErrorsIgnorePattern) {
      mergedOptions.caughtErrorsIgnorePattern = new RegExp(options.caughtErrorsIgnorePattern);
    }
  }
  private mergeDestructuredArray(options: Options, mergedOptions: TranslatedOptions): void {
    if (typeof options === 'object' && options?.destructuredArrayIgnorePattern) {
        mergedOptions.destructuredArrayIgnorePattern = new RegExp(options.destructuredArrayIgnorePattern);
    }
  }

  private mergeBooleanFlags(options: Options, mergedOptions: TranslatedOptions): void {
    if ( typeof options === 'object' && options?.ignoreClassWithStaticInitBlock !== undefined) {
      mergedOptions.ignoreClassWithStaticInitBlock =
        options.ignoreClassWithStaticInitBlock;
    }
    if ( typeof options === 'object' && options?.ignoreRestSiblings !== undefined) {
      mergedOptions.ignoreRestSiblings = options.ignoreRestSiblings;
    }
    if (typeof options === 'object' && options?.reportUsedIgnorePattern !== undefined) {
      mergedOptions.reportUsedIgnorePattern = options.reportUsedIgnorePattern;
    }
  }

  private mergeVars(options: Options, mergedOptions: TranslatedOptions): void {
    if (typeof options === 'object' && options?.vars) {
      mergedOptions.vars = options.vars;
    }
    if (typeof options === 'object' && options?.varsIgnorePattern) {
      mergedOptions.varsIgnorePattern = new RegExp(options.varsIgnorePattern);
    }
  }
  private getNoUsedVars( arkfile: ArkFile, exportNames: string[], methods: ArkMethod[], mergedOptions: TranslatedOptions,
    nameSpaceTrue: boolean,
    parenttFtrue: boolean
  ): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    let usedAllGlobalsKeys: string[] = []; //存放全局被使用变量最后进行筛选(最优解)
    let usedArrayPartnGlobalsKeys: string[] = []; //存放全局被使用变量最后进行筛选(最优解)
    //处理函数
    nousedSet = this.processMethod(methods, arkfile, nameSpaceTrue, nousedSet);
    nousedSet = this.processBody(methods, exportNames, mergedOptions, nousedSet, usedAllGlobalsKeys, parenttFtrue, usedArrayPartnGlobalsKeys);
    return nousedSet;
  }
  private processMethod(methods: ArkMethod[], arkfile: ArkFile, nameSpaceTrue: boolean, nousedSet: noUseVars[]): noUseVars[] {
    for (const method of methods) {
      if (method.getName().startsWith('%')) {
        continue;
      }
      if (method.getDeclaringArkClass().getName() !== '%dflt') {
        continue;
      }
      let lineNum = method.getDeclareLines() ?? [-1];
      if (lineNum[0] === -1) {
        lineNum[0] = method.getLine() ?? -1;
      }
      let col = method.getColumn() ?? -1;
      const methodName = method.getName();
      const methodCode = method.getCode() ?? '';
      const posion = this.getAccuratePosition(methodCode, methodName);
      const lineNo = posion.line + lineNum[0] - 1;
      let colNo = posion.col;
      if (methodCode.startsWith(' ')) {
        colNo = col + colNo;
      }
      const methodSign = method.getSignature();
      const exitMethod = this.methodOrClassUsed(arkfile, methodSign, false);
      if (!method?.isExport() && !exitMethod && !nameSpaceTrue) {
        const methodName = method.getName();
        nousedSet.push({varType: VarType.Method, stmt: method.getBody()?.getCfg().getStmts()[0] ?? ({} as Stmt),
          declareStmt: method.getBody()?.getCfg().getStmts()[0] ?? ({} as Stmt),
          argPosion: [lineNo, colNo, colNo + methodName.length],
          arkMethod: method,
          name: methodName,
          filePath: method.getDeclaringArkFile().getFilePath(),
        });
      }
    }
    return nousedSet;
  }
  private processBody(methods: ArkMethod[], exportNames: string[], mergedOptions: TranslatedOptions, nousedSet: noUseVars[],
    usedAllGlobalsKeys: string[],
    parenttFtrue: boolean,
    usedArrayPartnGlobalsKeys: string[]
  ): noUseVars[] {
    for (const method of methods) {
      const methodStmts = method.getBody()?.getCfg().getStmts() ?? [];
      const arrayBindingPattern = this.getArrayBindingPatternParameters(method);
      const objArrayBindingPattern =
      this.getObjectBindingPatternParameters(method);
      let objArrayBindingPatternNames: { name?: string; methodParamIndex: number; elementIndex: number; }[] = [];
      if (objArrayBindingPattern.length > 0) {
        objArrayBindingPatternNames = this.extractObjectArrayBindingPatternNames(method);
      }
      const arrayBindingPatternNames = arrayBindingPattern.flatMap((param, paramIndex) => param.arrayElements
            ?.map((element, elementIndex) => ({ name: element.name, methodParamIndex: paramIndex, elementIndex: elementIndex,
            })).filter((item) => Boolean(item.name)) || []
      );
      const arrayElementNames = [
        ...objArrayBindingPatternNames,
        ...arrayBindingPatternNames,
      ];
      const usedGlobals = method.getBody()?.getUsedGlobals() ?? new Map<string, Value>();
      const globalKeys = usedGlobals ? Array.from(usedGlobals.keys()) : [];
      usedAllGlobalsKeys = usedAllGlobalsKeys.concat(globalKeys);
      this.execLocalandGlobal(method, usedGlobals, globalKeys, nousedSet, arrayElementNames, methodStmts,
        usedArrayPartnGlobalsKeys,
        parenttFtrue,
        exportNames,
        mergedOptions
      );
    }
    return nousedSet;
  }
  private extractObjectArrayBindingPatternNames(method: ArkMethod): { name: string; methodParamIndex: number; elementIndex: number }[] {
    return method.getParameters().flatMap((param, paramIndex) => this.extractObjectArrayPatterns( method.getCode()?.toString() ?? ''
      ).flatMap((objParam) => objParam.arrayElements?.map((element, elementIndex) => ({
              name: element.name, methodParamIndex: paramIndex, elementIndex: elementIndex})
            ).filter((item) => Boolean(item.name)) || [])
    );
  }

  private execLocalandGlobal(method: ArkMethod, usedGlobals: Map<string, Value>, globalKeys: string[],
    nousedSet: noUseVars[],
    arrayElementNames: {
      name?: string;
      methodParamIndex: number;
      elementIndex: number;
    }[],
    methodStmts: Stmt[],
    usedArrayPartnGlobalsKeys: string[],
    parenttFtrue: boolean,
    exportNames: string[],
    mergedOptions: TranslatedOptions
  ): void {
    const varLocal: Map<string, Local> =
      method.getBody()?.getLocals() ?? new Map<string, Local>();
    this.processLocalVar(varLocal, method, usedGlobals, globalKeys, nousedSet, usedArrayPartnGlobalsKeys,
      parenttFtrue,
      exportNames,
      mergedOptions
    );
    this.processOtherVarsity( methodStmts, arrayElementNames, globalKeys, method, nousedSet, usedGlobals);
  }
  private getArrayBindingPatternParameters(method: ArkMethod): Method_Param[] {
    return (method.getParameters() as unknown as Method_Param[]).filter( (param) => param.name === 'ArrayBindingPattern');
  }

  private getObjectBindingPatternParameters(method: ArkMethod): Method_Param[] {
    return (method.getParameters() as unknown as Method_Param[]).filter((param) => param.name === 'ObjectBindingPattern');
  }

  private processArrayBindingPatternVars(
    stmt: ArkAssignStmt, arrayElementNames: {name?: string; methodParamIndex: number; elementIndex: number;}[],
    globalKeys: string[], method: ArkMethod, nousedSet: noUseVars[]
  ) {
    if ((stmt.getLeftOp() as Var_base).name !== VarType.ArgsP) {
      return;
    }

    const unusedArrayElements = arrayElementNames.filter(
      (
        item
      ): item is {
        name: string;
        methodParamIndex: number;
        elementIndex: number;
      } => item.name !== undefined && !globalKeys.includes(item.name)
    );

    for (const unusedParam of unusedArrayElements) {
      const position = this.computeVariablePosition(method, unusedParam.name, unusedParam.methodParamIndex);
      const filePath = method.getDeclaringArkFile().getFilePath();
      nousedSet.push({varType: VarType.ArgsP, stmt: stmt, name: unusedParam.name, declareStmt: this.isMyselfDec(stmt),
        isMethodParam: true,
        paramIndex: unusedParam.methodParamIndex,
        methodName: method.getName(),
        argPosion: position,
        filePath: filePath,
      });
    }
  }

  private processObjectBindingPatternVars(
    stmt: ArkAssignStmt, arrayElementNames: {name?: string; methodParamIndex: number; elementIndex: number;}[],
    globalKeys: string[], method: ArkMethod, nousedSet: noUseVars[]
  ) {
    if ((stmt.getLeftOp() as Var_base).name !== 'ObjectBindingPattern') {
      return;
    }

    const unusedArrayElements = arrayElementNames.filter(
      (
        item
      ): item is {
        name: string;
        methodParamIndex: number;
        elementIndex: number;
      } => item.name !== undefined && !globalKeys.includes(item.name)
    );

    for (const unusedParam of unusedArrayElements) {
      const position = this.computeVariablePosition(method, unusedParam.name, unusedParam.methodParamIndex);
      const filePath = method.getDeclaringArkFile().getFilePath();

      nousedSet.push({varType: VarType.ArgsP, stmt: stmt, name: unusedParam.name, declareStmt: this.isMyselfDec(stmt),
        isMethodParam: true, paramIndex: unusedParam.methodParamIndex, arkMethod: method, methodName: method.getName(),
        argPosion: position, filePath: filePath,
      });
    }
  }

  private processRegularVars(stmt: ArkAssignStmt, globalKeys: string[], method: ArkMethod, 
    nousedSet: noUseVars[], usedGlobals: Map<string, Value>
  ): void {
    const left = stmt.getLeftOp() as Var_base;
    if (
      !left.name ||
      left.name === 'this' ||
      this.isVarUsed(left, false, usedGlobals, method)
    ) {
      return;
    }
    if (globalKeys.includes(left.name)) {
      nousedSet.push({
        varType: VarType.Var,
        stmt: stmt,
        declareStmt: this.isMyselfDec(stmt),
        name: left.name.toString(),
        local: 'all',
      });
    }
  }
  private computeVariablePosition(method: ArkMethod, varName: string, methodParamIndex: number): [number, number, number] {
    const lineNo = method.getLine() ?? -1;
    const methodIndex = method.getCode()?.indexOf(method.getName()) ?? 0 + method.getName().length ?? -1;
    const paramIndex = method.getCode()?.indexOf(varName) ?? -1;
    let startCol = paramIndex;
    if (methodIndex > paramIndex) {
      startCol = methodIndex + 1 + methodParamIndex + varName.length;
    }
    return [lineNo, startCol, startCol + varName.length];
  }
  private processOtherVarsity(
    methodStmts: Stmt[], arrayElementNames: { name?: string; methodParamIndex: number; elementIndex: number;}[],
    globalKeys: string[], method: ArkMethod, nousedSet: noUseVars[], usedGlobals: Map<string, Value>
  ) {
    for (const stmt of methodStmts) {
      if (stmt instanceof ArkAssignStmt) {
        this.processArrayBindingPatternVars(stmt, arrayElementNames, globalKeys, method, nousedSet);
        this.processObjectBindingPatternVars(stmt, arrayElementNames, globalKeys, method, nousedSet);
        this.processRegularVars(stmt, globalKeys, method, nousedSet, usedGlobals);
      }
    }
  }

  private processLocalVar(
    varLocal: Map<string, Local>,
    method: ArkMethod,
    usedGlobals: Map<string, Value>,
    globalKeys: string[],
    nousedSet: noUseVars[],
    usedArrayPartnGlobalsKeys: string[],
    parenttFtrue: boolean,
    exportNames: string[],
    mergedOptions: TranslatedOptions
  ): void {
    let maxProcess = 0; // 记录最大使用下标
    for (const [key, local] of varLocal) {
      const localType = local.getType() as unknown as {
        methodSignature: MethodSignature;
      };
      if (localType?.methodSignature || key === 'this') {
        continue;
      }

      const declaringStmt = local.getDeclaringStmt() as unknown as {
        rightOp: { paramType?: any; index?: number };
      };
      const export_type = local
        .getDeclaringStmt()
        ?.getOriginalText()
        ?.trim()
        ?.startsWith('export');
      if (export_type) {
        continue; //如果是export直接忽略掉
      }
      const stmt = local.getDeclaringStmt();
      this.execDeclareStmt(
        key,
        declaringStmt,
        stmt,
        method,
        usedGlobals,
        globalKeys,
        nousedSet,
        usedArrayPartnGlobalsKeys,
        parenttFtrue,
        exportNames,
        mergedOptions
      );
      maxProcess = this.execDeclareStmtIndex(
        key,
        declaringStmt,
        stmt,
        method,
        usedGlobals,
        nousedSet,
        maxProcess
      );
    }
    nousedSet = nousedSet.map((item) =>
      item.methodName === method.getName()
        ? { ...item, parammaxUsedIndex: maxProcess }
        : item
    );
  }

  private execDeclareStmt(
    key: string,
    declaringStmt: { rightOp: { paramType?: any; index?: number } },
    stmt: Stmt | null,
    method: ArkMethod,
    usedGlobals: Map<string, Value>,
    globalKeys: string[],
    nousedSet: noUseVars[],
    usedArrayPartnGlobalsKeys: string[],
    parenttFtrue: boolean,
    exportNames: string[],
    mergedOptions: TranslatedOptions
  ): void {
    if (
      key === 'ArrayBindingPattern' ||
      key === 'ObjectBindingPattern' ||
      declaringStmt?.rightOp?.paramType
    ) {
      return;
    }
    if (stmt instanceof ArkAssignStmt) {
      const left = stmt.getLeftOp() as Var_base;
      const leftName = left?.name?.toString() ?? '';
      const rightOp = stmt.getRightOp();

      if (!leftName || leftName.includes('%')) {
        return;
      }
      if (!this.isVarUsed(left, false, usedGlobals, method)) {
        this.handleUnusedVariable(
          stmt,
          leftName,
          rightOp,
          nousedSet,
          globalKeys,
          method,
          parenttFtrue,
          exportNames
        );
      } else {
        this.handleUsedIgnorePattern(stmt, leftName, nousedSet, mergedOptions);
      }

      this.handleArrayPattern(
        stmt,
        leftName,
        usedArrayPartnGlobalsKeys,
        method
      );
    }
  }

  private execDeclareStmtIndex(
    key: string,
    declaringStmt: { rightOp: { paramType?: any; index?: number } },
    stmt: Stmt | null,
    method: ArkMethod,
    usedGlobals: Map<string, Value>,
    nousedSet: noUseVars[],
    maxProcess: number
  ): number {
    if (
      !key.includes('%dflt') &&
      key !== 'ArrayBindingPattern' &&
      key !== 'ObjectBindingPattern' &&
      declaringStmt?.rightOp?.paramType
    ) {
      if (stmt instanceof ArkAssignStmt) {
        const left = stmt.getLeftOp() as Var_base;
        const methoodCode = method.getCode() ?? '';
        const bodyCode = this.extractMethodBody(methoodCode);
        const leftName = left?.name?.toString();
        const paramIndex = declaringStmt.rightOp.index;
        if (
          leftName &&
          !(
            this.isVarUsed(left, true, usedGlobals, method) ||
            method.getName() === 'constructor' ||
            this.isTextUsed(bodyCode, leftName)
          )
        ) {
          const position = this.getPosionParamsIndex(method, leftName);

          const filePath = method.getDeclaringArkFile().getFilePath();
          nousedSet.push({
            varType: VarType.Args,
            stmt,
            declareStmt: this.isMyselfDec(stmt),
            name: leftName,
            isMethodParam: true,
            paramIndex,
            methodName: method.getName(),
            argPosion: position,
            filePath: filePath,
          });
        } else {
          maxProcess = Math.max(maxProcess, paramIndex ?? 0);
        }
      }
    }
    return maxProcess;
  }

  private getPosionParamsIndex(
    method: ArkMethod,
    leftName: string
  ): [number, number, number] {
    const lineNo = method.getLine() ?? -1; //函数内参数stmt未关联位置方案代替
    const methodCode = method.getCode() ?? '';
    const methodName = method.getName() ?? ''; // Ensure leftName is defined
    const lines = methodCode.split('\n'); // Split code into lines
    let methodInex = -1;
    let paramInex = -1;
    let startCol = -1;
    for (let i = 0; i < lines.length; i++) {
      methodInex = lines[i].indexOf(methodName);
      if (methodInex !== -1) {
        break;
      }
    }
    for (let i = 0; i < lines.length; i++) {
      paramInex = lines[i].indexOf(leftName);
      if (paramInex !== -1) {
        break;
      }
    }
    if (methodInex > paramInex) {
      startCol = methodInex + 1 + (paramInex ?? 0) + leftName.length;
    } else {
      startCol = paramInex;
    }

    const position: [number, number, number] = [
      lineNo,
      startCol,
      startCol + leftName.length,
    ];
    return position;
  }

  /**
   * 处理未使用变量的逻辑
   */
  private handleUnusedVariable(
    stmt: ArkAssignStmt,
    leftName: string,
    rightOp: any,
    nousedSet: noUseVars[],
    globalKeys: string[],
    method: ArkMethod,
    parenttFtrue: boolean,
    exportNames: string[]
  ): void {
    const originalText = stmt.getOriginalText()?.trim() ?? '';
    const isDestructuredArray =
      leftName.startsWith('[') && leftName.endsWith(']');
    const varInit = stmt.getRightOp().toString() !== 'undefined';

    if (this.isSpecialCase(originalText, stmt, leftName, nousedSet)) {
      return;
    }
    if (
      this.isDestructuredArrayCase(
        leftName,
        isDestructuredArray,
        stmt,
        globalKeys,
        varInit,
        nousedSet
      )
    ) {
      return;
    }
    if (this.isCaughtVariableCase(rightOp, leftName, stmt, nousedSet)) {
      return;
    }
    this.handleDefaultCase(
      leftName,
      stmt,
      method,
      parenttFtrue,
      exportNames,
      varInit,
      nousedSet
    );
  }
  private isSpecialCase(
    originalText: string,
    stmt: ArkAssignStmt,
    leftName: string,
    nousedSet: noUseVars[]
  ): boolean {
    if (originalText.includes('...') || this.isOherDeclareStmt(stmt)) {
      this.addNoUseVar(leftName, stmt, 'local', true, false, true, nousedSet);
      return true;
    } else if (originalText.split('=')[0].endsWith(']')) {
      this.addNoUseVar(leftName, stmt, 'local', true, false, true, nousedSet);
      return true;
    }
    return false;
  }
  private isDestructuredArrayCase(
    leftName: string,
    isDestructuredArray: boolean,
    stmt: ArkAssignStmt,
    globalKeys: string[],
    varInit: boolean,
    nousedSet: noUseVars[]
  ): boolean {
    if (isDestructuredArray) {
      const vars = this.getDestructuredArrayVars(leftName, globalKeys);
      vars.forEach((variable) => {
        this.addNoUseVar(
          variable,
          stmt,
          'local',
          false,
          varInit,
          false,
          nousedSet
        );
      });
      return true;
    }
    return false;
  }
  private isCaughtVariableCase(
    rightOp: any,
    leftName: string,
    stmt: ArkAssignStmt,
    nousedSet: noUseVars[]
  ): boolean {
    if (rightOp.toString().startsWith('caught')) {
      nousedSet.push({
        varType: VarType.Catch,
        stmt,
        declareStmt: this.isMyselfDec(stmt),
        name: leftName,
      });
      return true;
    }
    return false;
  }

  private handleDefaultCase(
    leftName: string,
    stmt: ArkAssignStmt,
    method: ArkMethod,
    parenttFtrue: boolean,
    exportNames: string[],
    varInit: boolean,
    nousedSet: noUseVars[]
  ): void {
    if (
      !(method?.getName() === '%dflt' && parenttFtrue) &&
      !exportNames.includes(leftName)
    ) {
      this.addNoUseVar(
        leftName,
        stmt,
        'local',
        false,
        varInit,
        false,
        nousedSet
      );
    }
  }
  private getDestructuredArrayVars(
    leftName: string,
    globalKeys: string[]
  ): string[] {
    return leftName
      .replace(leftNameReg, '')
      .split(',')
      .map((v) => v.trim())
      .filter((v) => v && !globalKeys.includes(v));
  }
  private addNoUseVar(
    leftName: string,
    stmt: ArkAssignStmt,
    local: 'local' | 'all',
    isMethodParam: boolean,
    varInit: boolean,
    isRestSiblings: boolean,
    nousedSet: noUseVars[]
  ): void {
    nousedSet.push({
      varType: VarType.Var,
      stmt: this.isMyselfMaxDec(stmt),
      declareStmt: this.isMyselfDec(stmt),
      name: leftName,
      local,
      isMethodParam,
      varInit,
      isRestSiblings,
    });
  }

  /**
   * 处理已使用但符合 `reportUsedIgnorePattern` 规则的变量
   */
  private handleUsedIgnorePattern(
    stmt: ArkAssignStmt,
    leftName: string,
    nousedSet: noUseVars[],
    mergedOptions: TranslatedOptions
  ): void {
    if (
      mergedOptions.reportUsedIgnorePattern &&
      mergedOptions.varsIgnorePattern?.test(leftName)
    ) {
      nousedSet.push({
        varType: VarType.UsedIgnorePattern,
        stmt,
        declareStmt: this.isMyselfDec(stmt),
        name: leftName,
        local: 'local',
        isMethodParam: false,
      });
    }
  }

  /**
   * 处理 `ArrayBindingPattern` 相关逻辑
   */
  private handleArrayPattern(
    stmt: ArkAssignStmt,
    leftName: string,
    usedArrayPartnGlobalsKeys: string[],
    method: ArkMethod
  ): void {
    const originalText = stmt.getOriginalText() ?? '';
    if (
      !method.getName().includes('%df') &&
      originalText.split('=')[0].trim().endsWith(']') &&
      stmt.getRightOp().toString().startsWith('%') &&
      stmt.getRightOp().toString().endsWith(']')
    ) {
      usedArrayPartnGlobalsKeys.push(leftName);
    }
  }

  private isVarUsed(
    left: Var_base,
    ismethodParams: boolean,
    usedGlobals: Map<string, Value>,
    arkmethod: ArkMethod
  ): boolean {
    if (!left.usedStmts) {
      return false;
    }
    if (ismethodParams && left.usedStmts.length > 0) {
      return true;
    }
    const execStmtsResult = this.execUsedStmts(left);
    let globalResult = false;
    //追加全局的
    if (ismethodParams) {
      globalResult = this.execUsedGlobals(usedGlobals, left);
    }
    //遍历参数中调用
    const methodStmts = arkmethod.getBody()?.getCfg()?.getStmts() ?? [];
    const methodName = arkmethod.getName();
    const result = methodStmts.some((stmt) => {
      return this.execMethodStmt(stmt, left, methodName);
    });
    // 如果没有返回 true，表示没有使用
    return false || globalResult || execStmtsResult || result;
  }

  private execUsedStmts(left: Var_base): boolean {
    let originalText = '';
    const stmts = left.usedStmts ?? [];
    for (const stmt of stmts) {
      // 如果原始文本重复，跳过
      const stmtText = stmt.getOriginalText();
      if (originalText === stmtText) {
        continue;
      }
      // 如果 name 不相等，说明有使用，直接返回 true
      if (stmt instanceof ArkIfStmt) {
        return true;
      }

      if (
        stmt instanceof ArkAssignStmt &&
        left.declaringStmt !== (stmt.getLeftOp() as Var_base).declaringStmt
      ) {
        return true;
      }
      if (stmt instanceof ArkInvokeStmt) {
        return true;
      }
      //追加条件20250304 && || !=  &&= ||=
      if (
        stmt instanceof ArkAssignStmt &&
        stmt.getRightOp() instanceof AbstractBinopExpr
      ) {
        const abstractBinopExpr = stmt.getRightOp() as AbstractBinopExpr;
        const operator = abstractBinopExpr.getOperator().toString();
        if (
          abstractBinopExpr &&
          !['+', '+=', '-', '-=', '='].includes(operator)
        ) {
          return true;
        }
      }
      originalText = stmtText ?? ''; // 缓存原始文本，避免重复调用
    }
    return false;
  }

  private execUsedGlobals(
    usedGlobals: Map<string, Value>,
    left: Var_base
  ): boolean {
    for (const val of usedGlobals.values()) {
      const vall = val as Var_base;
      if (vall.usedStmts) {
       return this.foreachStmts(vall.usedStmts, left);
      }
    }
    return false;
  }

  private foreachStmts(stmsts: Stmt[], left: Var_base): boolean {
    for (const stmt of stmsts) {
      if (stmt instanceof ArkAssignStmt) {
        // Keep this case for special handling later if needed
      } else if (stmt instanceof ArkInvokeStmt) {
        if (this.isFieldNameMatched(stmt, left.name ?? '')) {
          return true;
        }
      }
    }
    return false;
  }

  private isFieldNameMatched(stmt: ArkInvokeStmt, fieldName: string): boolean {
    const args = stmt.getInvokeExpr().getArgs();
    for (const arg of args) {
      const decArg = arg as Var_base;
      const declareStmt = decArg.declaringStmt;
      if (declareStmt && declareStmt instanceof ArkAssignStmt) {
        const decAs = declareStmt.getRightOp() as unknown as {
          fieldSignature: FieldSignature;
        };
        if (decAs?.fieldSignature?.getFieldName() === fieldName) {
          return true;
        }
      }
    }
    return false;
  }

  private execMethodStmt(
    stmt: Stmt,
    left: Var_base,
    methodName: string
  ): boolean {
    if (stmt instanceof ArkInvokeStmt) {
      const originalText = stmt.getOriginalText() ?? '';
      if (this.isTextUsed(originalText, left.name ?? 'errorP')) {
        return true;
      }
      return stmt
        .getInvokeExpr()
        .getArgs()
        .some((arg) => arg.toString() === left.name);
    }
    if (stmt instanceof ArkReturnStmt) {
      return this.isTextUsed(
        stmt.getOriginalText() ?? '',
        left.name ?? 'errorP'
      );
    }
    if (
      stmt instanceof ArkAssignStmt &&
      stmt.getRightOp() instanceof AbstractInvokeExpr
    ) {
      const expre = stmt.getRightOp() as AbstractInvokeExpr;
      const methodSign = expre.getMethodSignature().getMethodSubSignature();
      if (methodSign.getMethodName() === methodName) {
        return false;
      }
      return expre.getArgs().some((arg) => arg.toString() === left.name);
    }
    if (
      stmt instanceof ArkAssignStmt &&
      stmt.getRightOp().getType() instanceof FunctionType
    ) {
      const originalText = stmt.getOriginalText() ?? '';
      if (this.isTextUsed(originalText, left.name ?? 'errorP')) {
        return true;
      }
    }
    return false;
  }

  private methodOrClassUsed(
    arkfile: ArkFile,
    signature: MethodSignature | ClassSignature,
    isClass: boolean
  ): boolean {
    const exportinfo = arkfile.getExportInfos();
    const exportNames =
      exportinfo.map((info) => {
        return info.getNameBeforeAs() || info.getOriginName();
      }) ?? [];
    if (isClass && signature instanceof ClassSignature) {
      const className = signature.getClassName() ?? '';
      return this.handleClass(arkfile, signature, exportNames, className);
    } else if (signature instanceof MethodSignature) {
      return this.handleStmts(arkfile, signature, isClass);
    }
    return false;
  }

  private handleClass(
    arkfile: ArkFile,
    signature: ClassSignature,
    exportNames: string[],
    className: string
  ): boolean {
    for (const clas of arkfile.getClasses() ?? []) {
      if (clas.getSignature() === signature) {
        continue;
      }
      const extendClass = clas.getExtendedClasses(); //Map<string, ArkClass>;
      const implents = clas.getImplementedInterfaceNames(); //string[]
      const extentClassSigns = Array.from(extendClass.values()).map(
        (arkClass) => arkClass.getSignature()
      );
      if (
        exportNames.includes(className) ||
        extentClassSigns.includes(signature) ||
        implents.includes(className)
      ) {
        return true;
      }
      const fields = clas.getFields();
      for (const item of fields) {
        let ui = item?.getType()?.getTypeString() ?? '-101p';
        if (this.isTextUsed(ui, className)) {
          return true;
        }
      }
    }
    return false;
  }

  private handleStmts(
    arkfile: ArkFile,
    signature: MethodSignature,
    isClass: boolean
  ): boolean {
    // 遍历所有方法
    for (const clas of arkfile.getClasses() ?? []) {
      const arkMethods = clas.getMethods();
      for (const arkMethod of arkMethods) {
        if (arkMethod.getSignature() === signature) {
          continue;
        }
        const stmts = arkMethod.getBody()?.getCfg().getStmts() ?? [];
        return this.handleIsUsedMethod(signature, isClass, stmts);
      }
    }
    return false;
  }

  private handleIsUsedMethod(
    signature: MethodSignature,
    isClass: boolean,
    stmts: Stmt[]
  ): boolean {
    for (const stmt of stmts) {
      if (
        stmt instanceof ArkAssignStmt &&
        stmt.getLeftOp().toString() === 'this'
      ) {
        continue;
      }
      if (
        isClass &&
        signature instanceof ClassSignature &&
        this.isClassAssigned(stmt, signature)
      ) {
        return true;
      } else if (!isClass && this.isMethodInvoked(stmt, signature)) {
        return true;
      }
    }
    return false;
  }

  private isClassAssigned(stmt: Stmt, signature: ClassSignature): boolean {
    if (!(stmt instanceof ArkAssignStmt)) {
      return false;
    }

    const right = stmt.getRightOp() as unknown as {
      classType: { classSignature?: ClassSignature };
    };

    const classname = signature?.getClassName() ?? '-false';
    const tighttype = stmt?.getRightOp()?.getType()?.getTypeString() ?? '-101p';
    const leftop = stmt.getLeftOp() as Var_base;

    // 检查左操作数的使用情况
    const isLeftOpUsed = this.checkLeftOpUsage(leftop, classname);

    // 检查右操作数是否是目标类
    if (this.isRightClassAssigned(right, signature, stmt)) {
      return true;
    }

    return this.isTextUsed(tighttype, classname) || isLeftOpUsed;
  }

  private checkLeftOpUsage(leftop: Var_base, classname: string): boolean {
    if (!leftop.usedStmts) {
      return false;
    }

    for (const stmt of leftop.usedStmts) {
      if (stmt instanceof ArkAssignStmt) {
        const leftCode = stmt.getLeftOp().getType().getTypeString();
        if (this.isTextUsed(leftCode, classname)) {
          return true;
        }
      }
    }
    return false;
  }

  private isRightClassAssigned(
    right: { classType: { classSignature?: ClassSignature } },
    signature: ClassSignature,
    stmt: ArkAssignStmt
  ): boolean {
    const left = stmt.getLeftOp() as unknown as { name: string };
    return (
      right.classType?.classSignature === signature &&
      left.name !== 'this' &&
      left.name !== '%dflt'
    );
  }

  private isMethodInvoked(
    stmt: Stmt,
    signature: MethodSignature | ClassSignature
  ): boolean {
    const invokeExpr = CheckerUtils.getInvokeExprFromStmt(stmt);
    return invokeExpr?.getMethodSignature() === signature;
  }

  // 辅助函数: 判断stmt是否在当前文件stmts 的定义语句中
  private isOherDeclareStmt(stmt: Stmt): boolean {
    for (const st of stmt?.getCfg()?.getStmts() ?? []) {
      if (st instanceof ArkAssignStmt) {
        const left = st.getLeftOp() as Var_base;
        if (
          left.declaringStmt === stmt &&
          (st.getOriginalText()?.includes('...') ?? false)
        ) {
          return true;
        }
      }
    }
    return false;
  }

  //获取未使用的自调用最后一个(填坑--->20250207)无法通过usedStmt只能遍历全部 ----注意无需判断是否被使用(大条件下已经是未使用)
  private isMyselfDec(stmt: Stmt): Stmt {
    let stmto = stmt;
    if (stmt instanceof ArkAssignStmt) {
      const left = stmt.getLeftOp() as Var_base;
      if (left.declaringStmt) {
        stmto = left.declaringStmt;
      }
    }
    return stmto;
  }

  //最后调用点
  private isMyselfMaxDec(stmt: Stmt): Stmt {
    let stmto = stmt;
    const stms = stmt?.getCfg()?.getStmts() ?? [];
    for (const st of stms) {
      if (st instanceof ArkAssignStmt) {
        const left = st.getLeftOp() as Var_base;
        if (left.declaringStmt === stmt) {
          stmto = st;
        }
      }
    }
    return stmto;
  }

  //获取过滤后的结果
  private filterUnuseds(
    mergedOptions: TranslatedOptions,
    unuseds: noUseVars[]
  ) {
    if (mergedOptions.vars === 'local') {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Var && item.local === 'all')
      );
    }
    if (mergedOptions.varsIgnorePattern) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Var && mergedOptions.varsIgnorePattern?.test(item.name.toString())));
    }
    if (mergedOptions.args === 'after-used') {
      unuseds = unuseds.filter((item) => !((item.parammaxUsedIndex ?? -1) > (item.paramIndex ?? -1)));
    }
    if (mergedOptions.args === 'none') {
      unuseds = unuseds.filter((item) => !item.isMethodParam);
    }
    if (mergedOptions.argsIgnorePattern) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Args && mergedOptions.argsIgnorePattern?.test(item.name.toString())));
    }
    if (mergedOptions.caughtErrors === 'none') {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Catch)); //过滤掉错误代码块参数
    }
    if (mergedOptions.caughtErrorsIgnorePattern) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Catch && mergedOptions.caughtErrorsIgnorePattern?.test(item.name.toString())));
    }
    if (mergedOptions.destructuredArrayIgnorePattern) {
      //4.1 destructuredArrayIgnorePattern
      unuseds = unuseds.filter((item) => !(item.varType === VarType.ArgsP && mergedOptions.destructuredArrayIgnorePattern?.test(
              item.name.toString()
            )
          )
      );
    }
    if (mergedOptions.ignoreRestSiblings) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Var && item.isRestSiblings)); //过滤掉同级
    }
    if (mergedOptions.ignoreClassWithStaticInitBlock) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.Class && item.static)); 
    }
    if (mergedOptions.reportUsedIgnorePattern) {
      unuseds = unuseds.filter((item) => !(item.varType === VarType.UsedIgnorePattern));
    }
    return unuseds;
  }

  //辅助函数: 通过正则获取函数特殊情况ObjectArrayPatterns
  private extractObjectArrayPatterns(paramStr: string) {
    const matches = [];
    let match;
    while ((match = objectArrayPatternsReg.exec(paramStr)) !== null) {
      matches.push({
        paramName: match[1], // 'p'
        arrayElements: match[2]
          .replace(arrayElementsReg, '')
          .split(',')
          .map((name) => ({
            name: name.trim(), // 去掉多余空格
          })),
      });
    }

    return matches;
  }

  //装配描述信息
  private addDescription(noUseVar: noUseVars): string {
    switch (noUseVar.varType) {
      case VarType.Var:
        return noUseVar.varInit
          ? `'${noUseVar.name}' is assigned a value but never used.`
          : `'${noUseVar.name}' is defined but never used.`;
      case VarType.Class:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Method:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Args:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.ArgsP:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Catch:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Static:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.UsedIgnorePattern:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Import:
        return `'${noUseVar.name}' is defined but never used.`;
      case VarType.Type:
        return `'${noUseVar.name}' is defined but never used.`;
      default:
        return 'Unknown type.';
    }
  }

  private addIssueReport(noUseVar: noUseVars): void {
    const severity = this.rule.alert ?? this.metaData.severity;
    const warnInfo = this.getLineAndColumn(noUseVar);

    // Handle specific cases based on varType
    this.setWarnInfoForVarType(noUseVar, warnInfo);

    if (warnInfo.startCol > -1) {
      const defect = this.createDefect(warnInfo, noUseVar, severity);
      this.issues.push(new IssueReport(defect, undefined));
      RuleListUtil.push(defect);
    }
  }

  private setWarnInfoForVarType(noUseVar: noUseVars, warnInfo: any): void {
    switch (noUseVar.varType) {
      case VarType.Args:
      case VarType.ArgsP:
      case VarType.Import:
      case VarType.Type:
      case VarType.Method:
        this.setWarnInfoForArgType(noUseVar, warnInfo);
        break;
      case VarType.Class:
        if (noUseVar.arkClass) {
          this.setWarnInfoForClass(noUseVar, warnInfo);
        } else if (noUseVar.arkNamespace) {
          this.setWarnInfoForNamespace(noUseVar, warnInfo);
        }
        break;
    }
  }

  private setWarnInfoForArgType(noUseVar: noUseVars, warnInfo: any): void {
    if (noUseVar.argPosion) {
      warnInfo.line = noUseVar.argPosion[0];
      warnInfo.startCol = noUseVar.argPosion[1];
      warnInfo.endCol = noUseVar.argPosion[2];
      warnInfo.filePath = noUseVar.filePath ?? '';
    }
  }

  private setWarnInfoForClass(noUseVar: noUseVars, warnInfo: any): void {
    const indexNum =
      noUseVar.arkClass?.getCode()?.indexOf(noUseVar.name.toString()) ?? -1;
    const strNum = noUseVar.arkClass?.getColumn() ?? -1;
    const startCol = indexNum + strNum;
    warnInfo.line = noUseVar.arkClass?.getLine() ?? -1;
    warnInfo.startCol = startCol;
    warnInfo.endCol = startCol + noUseVar.name.length;
    warnInfo.filePath =
      noUseVar.arkClass?.getDeclaringArkFile()?.getFilePath() ?? '';
  }

  private setWarnInfoForNamespace(noUseVar: noUseVars, warnInfo: any): void {
    const indexNum =
      noUseVar.arkNamespace?.getCode()?.indexOf(noUseVar.name.toString()) ?? -1;
    const strNum = noUseVar.arkNamespace?.getColumn() ?? -1;
    const startCol = indexNum + strNum;
    warnInfo.line = noUseVar.arkNamespace?.getLine() ?? -1;
    warnInfo.startCol = startCol;
    warnInfo.endCol = startCol + noUseVar.name.length;
    warnInfo.filePath =
      noUseVar.arkNamespace?.getDeclaringArkFile()?.getFilePath() ?? '';
  }

  private createDefect(
    warnInfo: any,
    noUseVar: noUseVars,
    severity: number
  ): Defects {
    return new Defects(
      warnInfo.line,
      warnInfo.startCol,
      warnInfo.endCol,
      this.addDescription(noUseVar),
      severity,
      this.rule.ruleId,
      warnInfo.filePath,
      this.metaData.ruleDocPath,
      true,
      false,
      false
    );
  }

  private getLineAndColumn(noUseVar: noUseVars): {
    line: number;
    startCol: number;
    endCol: number;
    filePath: string;
  } {
    if (
      !noUseVar.stmt ||
      typeof noUseVar.stmt.getOriginPositionInfo !== 'function'
    ) {
      return { line: -1, startCol: -1, endCol: -1, filePath: '' };
    }

    const originPosition = noUseVar.stmt.getOriginPositionInfo();
    const arkMethod = noUseVar.arkMethod;
    const arkFile = noUseVar.stmt
      .getCfg()
      ?.getDeclaringMethod()
      ?.getDeclaringArkFile();

    const line =
      (originPosition?.getLineNo() ?? -1) >= 0
        ? originPosition.getLineNo()
        : arkMethod?.getLine() ?? -1;
    const originText = arkMethod
      ? arkMethod.getCode() ?? ''
      : noUseVar.stmt?.getOriginalText() ?? '';
    const startCol = this.getStartColumn(
      originPosition,
      arkMethod,
      originText,
      noUseVar.name.toString()
    );

    if (startCol === -1 || !arkFile) {
      return { line, startCol: -1, endCol: -1, filePath: '' };
    }

    const endCol = startCol + noUseVar.name.toString().length - 1;
    return { line, startCol, endCol, filePath: arkFile.getFilePath() };
  }

  private getStartColumn(
    originPosition: any,
    arkMethod: any,
    originText: string,
    varName: string
  ): number {
    let startCol =
      originPosition.getColNo() > -1
        ? originPosition.getColNo()
        : arkMethod?.getColumn() ?? -1;
    const pos = originText.indexOf(varName);
    return pos !== -1 ? startCol + pos : -1;
  }

  //获取所有箭头函数使用的全局变量
  loopNode(
    targetFile: ArkFile,
    sourceFile: ts.SourceFile,
    aNode: ts.Node,
    usedGlobalP: string[] = [] // 在递归调用时保持所有的全局变量
  ): string[] {
    const children = aNode.getChildren();
    for (const node of children) {
      if (ts.isArrowFunction(node)) {
        // 提取箭头函数的参数
        const params: string[] = [];
        const cd = node.parameters;
        for (const cdd of cd) {
          if (ts.isParameter(cdd)) {
            const cfd = cdd.getChildren();
            for (const cds of cfd) {
              if (ts.isIdentifier(cds)) {
                params.push(cds.getText());
              }
            }
          }
        }
        // 检查箭头函数体内的全局变量（比如 num）
        if (ts.isBlock(node.body)) {
          // 如果箭头函数体是块语句，递归检查每个子节点
          node.body.statements.forEach((statement) => {
            if (ts.isExpressionStatement(statement)) {
              const expr = statement.expression;
              if (
                ts.isIdentifier(expr) &&
                params.indexOf(expr.getText()) === -1
              ) {
                // 如果是标识符，且不在参数列表中，视为全局变量
                usedGlobalP.push(expr.getText());
              }
            }
          });
        } else if (
          ts.isIdentifier(node.body) &&
          params.indexOf(node.body.getText()) === -1
        ) {
          // 如果箭头函数体是一个简单的标识符（例如 num），并且它不在参数列表中
          usedGlobalP.push(node.body.getText());
        }
        // 递归调用，继续遍历子节点
        if (node.getChildren().length > 0) {
          this.loopNode(targetFile, sourceFile, node, usedGlobalP);
        }
      } else {
        // 对于非箭头函数节点，继续递归遍历子节点
        ts.forEachChild(node, (child) => {
          this.loopNode(targetFile, sourceFile, child, usedGlobalP);
        });
      }
    }
    return usedGlobalP; // 返回最终的所有 usedGlobalP
  }

  //判断换class中是否包含static块
  hasStaticBlock(sourceFile: ts.SourceFile): boolean {
    for (let child of sourceFile.statements) {
      return this.loopStatic(sourceFile, child);
    }
    return false;
  }

  loopStatic(sourceFile: ts.SourceFile, aNode: ts.Node): boolean {
    const children = aNode.getChildren();
    for (const node of children) {
      if (ts.isClassStaticBlockDeclaration(node)) {
        return true;
      }
      if (node.getChildren().length > 0) {
        return this.loopStatic(sourceFile, node);
      }
    }
    return false;
  }

  private collectImports(
    node: ts.Node,
    astRoot: ts.SourceFile,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    if (ts.isImportDeclaration(node)) {
      this.processImportDeclaration(node, astRoot, importMap);
    }

    ts.forEachChild(node, (child) =>
      this.collectImports(child, astRoot, importMap)
    );
  }

  private processImportDeclaration(
    node: ts.ImportDeclaration,
    astRoot: ts.SourceFile,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    const moduleText = node.moduleSpecifier.getText(astRoot);
    const importClause = node.importClause;

    if (importClause) {
      if (importClause.name) {
        this.processDefaultImport(
          importClause.name.text,
          moduleText,
          importMap
        );
      }

      if (importClause.namedBindings) {
        this.processNamedBindings(
          importClause.namedBindings,
          moduleText,
          importMap
        );
      }
    }
  }

  private processDefaultImport(
    defaultImportName: string,
    source: string,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    importMap.set(defaultImportName, {
      used: false,
      source: source,
    });
  }

  private processNamedBindings(
    namedBindings: ts.ImportClause['namedBindings'],
    source: string,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    if (namedBindings && ts.isNamedImports(namedBindings)) {
      this.processNamedImports(namedBindings, source, importMap);
    } else if (namedBindings && ts.isNamespaceImport(namedBindings)) {
      this.processNamespaceImport(namedBindings, source, importMap);
    }
  }

  private processNamedImports(
    namedImports: ts.NamedImports,
    source: string,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    for (const element of namedImports.elements) {
      importMap.set(element.name.text, {
        used: false,
        source: source,
      });
    }
  }

  private processNamespaceImport(
    namespaceImport: ts.NamespaceImport,
    source: string,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    importMap.set(namespaceImport.name.text, {
      used: false,
      source: source,
    });
  }

  // 辅助函数：递归遍历 AST 检查标识符的使用情况
  private checkUsage(
    node: ts.Node,
    astRoot: ts.SourceFile,
    importMap: Map<string, { used: boolean; source: string }>
  ): void {
    if (ts.isIdentifier(node)) {
      // 排除在导入声明中的标识符
      if (
        node.parent &&
        (ts.isImportSpecifier(node.parent) ||
          ts.isImportClause(node.parent) ||
          ts.isNamespaceImport(node.parent))
      ) {
        // 忽略
      } else {
        if (importMap.has(node.text)) {
          const info = importMap.get(node.text)!;
          info.used = true;
          importMap.set(node.text, info);
        }
      }
    }
    ts.forEachChild(node, (child) =>
      this.checkUsage(child, astRoot, importMap)
    );
  }

  // 主函数：检测未使用的导入
  private noUsedImport(astRoot: ts.SourceFile): string[] {
    const importMap = new Map<string, { used: boolean; source: string }>();
    const noUsedImports: string[] = [];
    // 1. 收集导入信息
    this.collectImports(astRoot, astRoot, importMap);

    // 2. 检查标识符使用情况
    this.checkUsage(astRoot, astRoot, importMap);

    // 3. 输出未使用的导入
    for (const [name, info] of importMap.entries()) {
      if (!info.used) {
        noUsedImports.push(name);
      }
    }
    return noUsedImports;
  }

  private collectTypes(
    node: ts.Node,
    astRoot: ts.SourceFile,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (ts.isTypeAliasDeclaration(node)) {
      const isExported = node.modifiers && node.modifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
      typeMap.set(node.name.text, {used: isExported ? true : false, kind: 'type别名', pos: node.name.getStart(astRoot)});
    } else if (ts.isInterfaceDeclaration(node)) {
      const isExported = node.modifiers && node.modifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
      typeMap.set(node.name.text, {used: isExported ? true : false, kind: '接口', pos: node.name.getStart(astRoot)});
    }
    ts.forEachChild(node, (child) =>
      this.collectTypes(child, astRoot, typeMap)
    );
  }

  private checkTypeUsage(
    node: ts.Node,
    astRoot: ts.SourceFile,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (ts.isIdentifier(node) && node.parent) {
      if (!this.isTypeDeclaration(node) && !this.isDefaultExport(node)) {
        this.markTypeAsUsed(node, typeMap);
      }
    }

    ts.forEachChild(node, (child) =>
      this.checkTypeUsage(child, astRoot, typeMap)
    );
  }

  private isTypeDeclaration(node: ts.Identifier): boolean {
    return (
      ts.isTypeAliasDeclaration(node.parent) && node.parent.name === node
    );
  }

  private isDefaultExport(node: ts.Identifier): boolean {
    return (
      ts.isExportAssignment(node.parent) && node.parent.isExportEquals === false
    );
  }

  private markTypeAsUsed(
    node: ts.Identifier,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (typeMap.has(node.text)) {
      const info = typeMap.get(node.text)!;
      info.used = true;
      typeMap.set(node.text, info);
    }
  }

  // 主函数，返回未使用类型的数组，并附带行列号信息
  private noUsedType(astRoot: ts.SourceFile): astType[] {
    const typeMap = new Map<string, { used: boolean; kind: string; pos: number }>();
    const noUsedTypes: { name: string; kind: string; line: number; character: number;}[] = [];
    this.collectTypes(astRoot, astRoot, typeMap);
    this.checkTypeUsage(astRoot, astRoot, typeMap);
    for (const [name, info] of typeMap.entries()) {
      if (!info.used) {
        const { line, character } = astRoot.getLineAndCharacterOfPosition(
          info.pos
        );
        // 注意：行列号从 0 开始，所以返回时加 1
        noUsedTypes.push({name, kind: info.kind, line: line + 1, character: character + 1});
      }
    }
    return noUsedTypes;
  }

  private getAccuratePosition(codeImport: string, name: string): { line: number; col: number } {
    const lines = codeImport.split('\n');
    // 转义 name 中的正则特殊字符
    const escapedName = name.replace(accuratePositionReg, '\\$&');
    // 使用正则，确保匹配完整的标识符（前后是非字母数字或下划线）
    const regex = new RegExp(`\\b${escapedName}\\b`, 'g');
    for (let i = 0; i < lines.length; i++) {
      let match;
      while ((match = regex.exec(lines[i])) !== null) {
        return { line: i + 1, col: match.index + 1 }; // 返回行号和列号
      }
    }
    return { line: -1, col: -1 }; // 未找到
  }

  private isTextUsed(code: string, name: string): boolean {
    // 转义正则特殊字符
    const escapedName = name.replace(textUsedReg, '\\$&');
    // 正则匹配完整的标识符，并确保不在引号内
    const regex = new RegExp(`\\b${escapedName}\\b(?![^"']*["'])`, 'g');
    return regex.test(code);
  }

  private collectGenerics(
    node: ts.Node,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    // Handle the specific cases where generics are present
    this.handleGenerics(node, typeMap);
    // Recursively traverse child nodes
    ts.forEachChild(node, (child) => this.collectGenerics(child, typeMap));
  }

  // Handle the specific cases for type aliases, function declarations, and constructor type nodes
  private handleGenerics(
    node: ts.Node,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (ts.isTypeAliasDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
      this.collectTypeAliasGenerics(node, typeMap);
    }

    if (ts.isTypeAliasDeclaration(node) && ts.isConstructorTypeNode(node.type)) {
      this.collectConstructorTypeGenerics(node, typeMap);
    }
  }

  // Collect generics for type aliases and function declarations
  private collectTypeAliasGenerics(
    node: | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.FunctionExpression,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (node.typeParameters) {
      node.typeParameters.forEach((typeParam) => {
        const genericKey = `${node.getText()}--->${typeParam.name.text}`;
        if (!typeMap.has(genericKey)) {
          typeMap.set(genericKey, {used: false, kind: typeParam.name.text, pos: typeParam.getStart()});
        }
      });
    }
  }

  // Collect generics for constructor type aliases
  private collectConstructorTypeGenerics(
    node: ts.TypeAliasDeclaration,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (node.typeParameters) {
      node.typeParameters.forEach((typeParam) => {
        const genericKey = `${node.getText()}-${typeParam.name.text}`;
        if (!typeMap.has(genericKey)) {
          typeMap.set(genericKey, {used: false, kind: typeParam.name.text, pos: typeParam.getStart()});
        }
      });
    }
  }

  private checkGenericUsage(
    node: ts.Node,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (ts.isTypeAliasDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
      this.checkReturnTypeUsage(node, typeMap);
      if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
        this.checkParameterTypeUsage(node, typeMap);
      }
      if (node.typeParameters) {
        this.checkTypeParameterUsage(node, typeMap);
      }
    }
    // 递归检查子节点
    ts.forEachChild(node, (child) => this.checkGenericUsage(child, typeMap));
  }

  // 检查函数返回值中的泛型
  private checkReturnTypeUsage(
    node: ts.SignatureDeclaration | ts.TypeAliasDeclaration,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    if (!node.type) {
      return;
    }

    const genericText = this.isGenericUsedInType(node.type);
    if (!genericText) {
      return;
    }

    const text = node.getText();
    const genericKey = `${text}--->${genericText}`;
    if (typeMap.has(genericKey)) {
      typeMap.get(genericKey)!.used = true;
    }
  }

  // 检查函数参数中的泛型
  private checkParameterTypeUsage(
    node: ts.FunctionDeclaration | ts.FunctionExpression,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    node.parameters.forEach((param) => {
      if (!param.type) {
        return;
      }

      const paramType = this.isGenericUsedInType(param.type);
      if (!paramType) {
        return;
      }

      const text = node.getText();
      const genericKey = `${text}--->${param.type.getText()}`;
      if (typeMap.has(genericKey)) {
        const info = typeMap.get(genericKey)!;
        info.used = true;
        info.kind = param.type.getText();
      }
    });
  }

  // 检查类型别名的泛型参数
  private checkTypeParameterUsage(
    node: ts.TypeAliasDeclaration | ts.SignatureDeclaration,
    typeMap: Map<string, { used: boolean; kind: string; pos: number }>
  ): void {
    node.typeParameters!.forEach((typeParam) => {
      const genericText = this.isGenericUsedInType(typeParam);
      if (!genericText) {
        return;
      }

      const text = node.getText();
      const genericKey = `${text}--->${typeParam.name.text}`;
      if (typeMap.has(genericKey)) {
        const info = typeMap.get(genericKey)!;
        info.used = true;
        info.kind = typeParam.name.text;
      }
    });
  }

  private isGenericUsedInType(node: ts.Node): string | null {
    if (!node) {
      return null;
    }

    if (ts.isTypeReferenceNode(node)) {
      return this.handleTypeReferenceNode(node);
    }

    if (ts.isInferTypeNode(node)) {
      return node.typeParameter.name.getText();
    }

    if (ts.isConditionalTypeNode(node)) {
      return this.handleConditionalTypeNode(node);
    }

    if (ts.isIndexedAccessTypeNode(node)) {
      return this.handleIndexedAccessTypeNode(node);
    }

    if (ts.isMappedTypeNode(node)) {
      return this.isGenericUsedInType(node.type ?? node.typeParameter);
    }

    if (ts.isFunctionTypeNode(node) || ts.isConstructorTypeNode(node)) {
      return this.handleFunctionTypeNode(node);
    }

    return this.checkChildrenForGeneric(node);
  }

  private handleTypeReferenceNode(node: ts.TypeReferenceNode): string | null {
    const typeName = node.typeName.getText();
    if (node.typeArguments) {
      for (const arg of node.typeArguments) {
        const genericName = this.isGenericUsedInType(arg);
        if (genericName) {
          return genericName;
        }
      }
    }
    return typeName;
  }

  private handleConditionalTypeNode(
    node: ts.ConditionalTypeNode
  ): string | null {
    return (this.isGenericUsedInType(node.checkType) || this.isGenericUsedInType(node.extendsType) || this.isGenericUsedInType(node.trueType) ||
      this.isGenericUsedInType(node.falseType)
    );
  }

  private handleIndexedAccessTypeNode(
    node: ts.IndexedAccessTypeNode
  ): string | null {
    return (this.isGenericUsedInType(node.objectType) || this.isGenericUsedInType(node.indexType) );
  }

  private handleFunctionTypeNode(
    node: ts.FunctionTypeNode | ts.ConstructorTypeNode
  ): string | null {
    for (const param of node.parameters) {
      if (param.type) {
        const paramType = this.isGenericUsedInType(param.type);
        if (paramType) {
          return paramType;
        }
      }
    }
    return this.isGenericUsedInType(node.type);
  }

  private checkChildrenForGeneric(node: ts.Node): string | null {
    let firstGeneric: string | null = null;
    ts.forEachChild(node, (child) => {
      firstGeneric = this.isGenericUsedInType(child);
      if (firstGeneric) {
        return;
      }
    });
    return firstGeneric;
  }

  private getUnusedGenerics(astRoot: ts.SourceFile): astType[] {
    const typeMap = new Map<string, { used: boolean; kind: string; pos: number }>();
    const unusedGenerics: { name: string; kind: string; line: number; character: number;}[] = [];

    // 1. 收集所有的泛型声明（包括类型别名、函数签名中的泛型等）
    this.collectGenerics(astRoot, typeMap);

    // 2. 遍历 AST 检查这些泛型是否被使用
    this.checkGenericUsage(astRoot, typeMap);

    // 3. 输出未使用的泛型
    for (const [name, info] of typeMap.entries()) {
      if (!info.used) {
        const { line, character } = astRoot.getLineAndCharacterOfPosition(
          info.pos
        );
        unusedGenerics.push({name: info.kind, kind: info.kind, line: line + 1, character: character + 1});
      }
    }
    return unusedGenerics;
  }

  private recursiveSearch(
    namespaces: ArkNamespace[],
    result: ArkNamespace[]
  ): void {
    for (const ns of namespaces) {
      result.push(ns); // 记录当前命名空间

      // 确保 getNamespaces() 存在且返回的是数组
      const subNamespaces = ns.getNamespaces?.();
      if (Array.isArray(subNamespaces)) {
        this.recursiveSearch(subNamespaces, result); // 递归调用子命名空间
      }
    }
  }

  private getAllNamespaces(targetFile: ArkFile): ArkNamespace[] {
    const result: ArkNamespace[] = [];
    const namespaces = targetFile.getNamespaces?.(); // 确保 getNamespaces() 存在
    if (Array.isArray(namespaces)) {
      this.recursiveSearch(namespaces, result);
    }
    return result;
  }

  // 递归遍历 AST
  private traverseAST(node: ts.Node, namespaceName: string): boolean {
    // 如果节点为空，或者已经找到了命名空间使用，直接返回 true
    if (!node) {
      return false;
    }

    // 处理 PropertyAccessExpression 这种访问（MyNamespace.greet()）
    if (node.kind === ts.SyntaxKind.PropertyAccessExpression) {
      const propertyAccess = node as ts.PropertyAccessExpression;
      // 检查访问的对象是否是命名空间 MyNamespace
      if ( propertyAccess.expression.kind === ts.SyntaxKind.Identifier && (propertyAccess.expression as ts.Identifier).text === namespaceName) {
        // 如果访问的属性（函数或变量）也匹配
        return true;
      }
    }

    // 处理 QualifiedName 这种类型引用（MyNamespace.SomeType）
    if (node.kind === ts.SyntaxKind.QualifiedName) {
      const qualifiedName = node as ts.QualifiedName;
      if ( qualifiedName.left.kind === ts.SyntaxKind.Identifier && (qualifiedName.left as ts.Identifier).text === namespaceName) {
        return true; // 找到命名空间 MyNamespace 被引用
      }
    }

    // 递归遍历子节点
    return (
      ts.forEachChild(node, (childNode) => {
        return this.traverseAST(childNode, namespaceName); // 一旦找到目标，递归会返回 true
      }) || false
    ); // 如果没有找到任何子节点使用该命名空间，返回 false
  }

  // `isNamespaceUsed` 方法调用外部 `traverseAST`
  private isNamespaceUse(
    arkfile: ArkFile,
    namespaceSignature: NamespaceSignature
  ): boolean {
    for (const clasz of arkfile.getClasses()) {
      for (const method of clasz.getMethods()) {
        if (this.isMethodUsingNamespace(method, namespaceSignature)) {
          return true;
        }
      }
    }
    return false;
  }

  private isMethodUsingNamespace(
    method: ArkMethod,
    namespaceSignature: NamespaceSignature
  ): boolean {
    const stmts = method.getBody()?.getCfg()?.getStmts() ?? [];
    for (const stmt of stmts) {
      if (stmt instanceof ArkInvokeStmt && this.isInvokeUsingNamespace(stmt, namespaceSignature)) {
        return true;
      }
    }
    return false;
  }

  private isInvokeUsingNamespace(
    stmt: ArkInvokeStmt,
    namespaceSignature: NamespaceSignature
  ): boolean {
    const invokeExpr = stmt.getInvokeExpr();
    const methodSignature = invokeExpr.getMethodSignature();
    if (methodSignature instanceof NamespaceSignature && methodSignature === namespaceSignature) {
      return true;
    }
    const args = invokeExpr.getArgs();
    for (const arg of args) {
      if (this.isArgumentUsingNamespace(arg, namespaceSignature)) {
        return true;
      }
    }
    return false;
  }

  private isArgumentUsingNamespace( arg: any, namespaceSignature: NamespaceSignature): boolean {
    const varBaseArg = arg as Var_base;
    if (varBaseArg && varBaseArg.declaringStmt instanceof ArkAssignStmt) {
      const origText = varBaseArg.declaringStmt.getOriginalText() ?? '';
      if (this.isTextUsed(origText, namespaceSignature.getNamespaceName())) {
        return true;
      }
    }
    return false;
  }

  //获取方法体code
  private extractMethodBody(methodCode: string): string {
    let braceCount = 0;
    let startIndex = -1;
    // 遍历代码，找到方法体的起始 `{`
    for (let i = 0; i < methodCode.length; i++) {
      if (methodCode[i] === '{') {
        if (startIndex === -1) {
          startIndex = i; // 记录第一个 `{`
        }
        braceCount++;
      } else if (methodCode[i] === '}') {
        braceCount--;
        if (braceCount === 0) {
          // 找到匹配的 `}`
          return methodCode.substring(startIndex + 1, i).trim();
        }
      }
    }
    // 如果没有找到完整的方法体，返回空字符串
    return '';
    ``;
  }

  private collectUnusedClasses(targetFile: ArkFile, exportNames: string[], mergedOptions: TranslatedOptions): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    for (const targetClass of targetFile.getClasses() ?? []) {
      let methods = targetClass.getMethods();
      const methodStatic = targetClass.getMethodWithName('%statBlock0'); //获取static块
      if (methodStatic) {
        methods.push(methodStatic);
      }
      const isDefault = targetClass.getName() === '%dflt';
      const isUsed = this.methodOrClassUsed(targetFile, targetClass.getSignature(), true);
      const isExported = targetClass?.isExport();
      const isInternal = targetClass.getName().startsWith('%');
      if (!(isExported || (!isDefault && isUsed)) && !isInternal) {
        if (methodStatic) {
          nousedSet.push({varType: VarType.Class, arkClass: targetClass, name: targetClass.getName(), static: true});
        } else {
          nousedSet.push({varType: VarType.Class, arkClass: targetClass, name: targetClass.getName() });
        }
      }
      nousedSet = nousedSet.concat(this.getNoUsedVars(targetFile, exportNames, methods, mergedOptions, false, false));
    }
    return nousedSet;
  }

  private collectUnusednameSpaces(namespaces: ArkNamespace[], targetFile: ArkFile, exportNames: string[],
    mergedOptions: TranslatedOptions): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    for (const namespace of namespaces) {
      const hui = namespace.getNamespaces();
      //1.将namespace 特殊处理 module也在其中module不处理
      const nameSpaceName = namespace.getName();
      let currentNamespace: ArkNamespace | undefined | null = namespace.getDeclaringArkNamespace();
      let namespaceName = currentNamespace?.getName() ?? '';
      namespace.getSignature();
      // 递归查找最外层命名空间用来判断是否export
      while (currentNamespace?.getDeclaringArkNamespace()) {
        currentNamespace = currentNamespace?.getDeclaringArkNamespace();
      }
      const nameSpaceTrue = namespace?.isDeclare() ?? false;
      const currentNamespaceTrue = currentNamespace?.isDeclare() ?? false;
      const namespaceCode = namespace?.getCode() ?? '';
      const methods = namespace.getAllMethodsUnderThisNamespace();
      if (
        !(namespaceName !== '' && currentNamespaceTrue) && !namespace.isExport() &&
        !this.isNamespaceUse(targetFile, namespace.getSignature()) && !this.isTextUsed(namespaceCode, 'module') &&
        !this.isTextUsed(namespaceCode, 'global') && !exportNames.includes(nameSpaceName) ) {
        nousedSet.push({varType: VarType.Class, arkNamespace: namespace, name: nameSpaceName
        });
      }
      nousedSet = nousedSet.concat(
        this.getNoUsedVars(targetFile, exportNames, methods, mergedOptions, nameSpaceTrue, currentNamespaceTrue || nameSpaceTrue
        )
      );
    }
    return nousedSet;
  }

  private collecUnusedImports(importInfos: ImportInfo[], targetFilePath: string, importNoused: string[]): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    for (const info of importInfos) {
      const lineNo = info.getOriginTsPosition().getLineNo();
      const codeImport = info.getTsSourceCode();
      const name2 = info.getOriginName();
      const posion = this.getAccuratePosition(codeImport, name2);
      if (importNoused.includes(name2)) {
        //处理未使用的import
        nousedSet.push({varType: VarType.Import,
          argPosion: [posion.line + lineNo - 1, posion.col, posion.col + name2.length], // Assign a default value or the appropriate value
          name: name2, filePath: targetFilePath
        });
      }
    }
    return nousedSet;
  }
  private collecUnusedTypes(noUsedtype: astType[], targetFilePath: string): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    for (const type of noUsedtype) {
      nousedSet.push({varType: VarType.Type,
        argPosion: [type.line, type.character, type.character], // Assign a default value or the appropriate value
        name: type.name, filePath: targetFilePath,
      });
    }
    return nousedSet;
  }
  private collecUnusedGenerics(generics: astType[], targetFilePath: string): noUseVars[] {
    let nousedSet: noUseVars[] = [];
    for (const generic of generics) {
      nousedSet.push({varType: VarType.Type,
        argPosion: [generic.line, generic.character, generic.character + generic.name.length], // Assign a default value or the appropriate value
        name: generic.name, filePath: targetFilePath,
      });
    }
    return nousedSet;
  }
}
